# -*- coding: utf-8 -*-
"""
 Copyright 2005 Spike^ekipS <spikeekips@gmail.com>

	This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""

import re, urlparse
from django import template
from django.http import HttpResponseRedirect, HttpResponse
from django.views.generic.list_detail import object_list, object_detail
from django.shortcuts import render_to_response as render_to_response_django, get_object_or_404
from django.db import models
from django.db.models import ObjectDoesNotExist

import models as models_search

import core, forms
import pylucene

models.get_apps()

class ObjectList (list) :
	def __init__ (self, query=None) :
		self.query = query

	def extend_by_hit (self, hits, query=None) :
		self.extend(
			[core.DocumentObject(i, query=query) for i in hits]
		)
	def set_raw_query (self, query) :
		self.query = pylucene.parse_query(query)
		return self.query

	def get_raw_query (self) :
		return self.query

	def _clone (self) :
		return self

	def count (self) :
		return len(self)

def render_to_response (request, *args, **kwargs) :
	kwargs.update(
		{"context_instance": template.RequestContext(request), }
	)
	return render_to_response_django(*args, **kwargs)

def check_auth (func) :
	def wrapper (request, **kwargs) :
		if not request.user.is_staff :
			return HttpResponse(content="<h1>UnAuthorized Request</h1>", status=401)

		return func(request, **kwargs)

	return wrapper

def match_func_by_method (func) :
	def wrapper (request, **kwargs) :
		try :
			if kwargs.has_key("_method") and kwargs.get("_method") in ("GET", "POST", "PUT", "DELETE", ) :
				__method = kwargs.get("_method")
			elif request.META["REQUEST_METHOD"] not in ("GET", "POST", "PUT", "DELETE", ) :
				__method = "POST"
			else :
				__method = request.META["REQUEST_METHOD"]

			__name = "%s_%s" % \
				( \
					__method.lower(), \
					func.func_name \
				)

			if not func.func_globals.has_key(__name) :
				return func(request, **kwargs)
			else :
				return func.func_globals.get(__name)(request, getattr(request, __method).copy(), **kwargs)

		except Exception, e :
			raise

	return wrapper

@check_auth
@match_func_by_method
def index (request) :
	model_list = list()
	for k, m in core.get_registered_model().items() :
		model_list.append(
			{
				"name": m._meta.verbose_name,
				"model_name": core.get_model_name(m),
				"model": m,
				"app_label": m._meta.app_label,
				"admin_url": u"%s/%s/" % (m._meta.app_label, m.__name__.lower(), ),
			}
		)

	return render_to_response(
		request,
		"search_admin_index.html",
		{
			"opts": models_search.Search._meta,
			"model_list": model_list,
			"reader": pylucene.Reader(),
			"form": forms.Search(),
		}
	)

def post_index (request, argument, **kwargs) :
	if kwargs.has_key("command") :
		__command = kwargs.get("command")
		if __command == "clean" : # clean up the all the model indexed object
			indexer = pylucene.Indexer().clean().close()
		elif __command == "optimize" : # clean up the all the model indexed object
			pylucene.Indexer().optimize().close()

		return HttpResponseRedirect(re.compile("/__%s__/$" % __command).sub("/", urlparse.urlparse(request.META.get("REQUEST_URI"))[2]))


@check_auth
def to_index (request) :
	return HttpResponseRedirect("/admin/search/")

@check_auth
@match_func_by_method
def model (request, model_name, **kwargs) :
	if model_name == "search" :
		return HttpResponseRedirect("/admin/search/")

	_model = core.get_registered_model().get(model_name, None)
	if not _model :
		raise ObjectDoesNotExist, "Model, '%s' is not related to Lucene Object." % model_name

	try :
		page = int(request.GET.get("page", 1))
	except :
		page = 1

	if page < 1 : page = 1

	# get object list
	return object_list(
		request,
		queryset=_model.get("model").objects_search.all(),
		paginate_by=20,
		page=page,
        allow_empty=True,
		extra_context={
			"opts": models_search.Search._meta,
			"opts_model": {
				"meta": _model.get("model")._meta,
				"model_name": _model.get("name"),
				"model": _model.get("model"),
			},
			"model": _model.get("model"),
		},
		template_name="search_admin_model.html",
	)

def post_model (request, argument, model_name, **kwargs) :
	_model = core.get_registered_model().get(model_name, None)
	if not _model :
		raise ObjectDoesNotExist, "Model, '%s' is not related to Lucene Object." % model_name

	elif kwargs.has_key("command") :
		__command = kwargs.get("command")
		if __command == "clean" : # clean up the all the model indexed object
			index_writer = pylucene.IndexWriter()
			index_writer.unindex_by_term(
				pylucene.create_term(
					core.FIELD_NAME_MODEL,
					core.get_model_name(_model.get("model")),
				)
			)
			index_writer.close()

		return HttpResponseRedirect(re.compile("/__clean__/$").sub("/", urlparse.urlparse(request.META.get("REQUEST_URI"))[2]))

	return HttpResponseRedirect(request.META.get("HTTP_REFERER"))

@check_auth
def model_object (request, model_name, object_id) :
	_model = core.get_registered_model().get(model_name, None)
	if not _model :
		raise ObjectDoesNotExist, "Model, '%s' is not related to Lucene Object." % model_name

	return object_detail(
		request,
		queryset=_model.get("model").objects_search.all(),
		object_id=object_id,
		template_name="search_admin_model_object.html",
		extra_context={
			"opts": models_search.Search._meta,
			"opts_model": {
				"meta": _model.get("model")._meta,
				"model_name": core.get_model_name(_model.get("model")),
				"model": _model.get("model"),
				"admin_url": u"%s/%s/" % (
					_model.get("model")._meta.app_label, _model.get("model").__name__.lower(), ),
			},
			"model": _model.get("model"),
			"reader": pylucene.Reader(),
		},
	)

@check_auth
@match_func_by_method
def search (request) :
	argument = request.POST.copy()
	try :
		page = int(argument.get("page", 0))
	except :
		page = 1

	if page < 1 : page = 1

	form = forms.Search(argument)
	query = argument.get("query")
	queryset = ObjectList(query=query)

	(hits, query, ) = core.search(query)
	if form.is_valid() :
		queryset.extend_by_hit(list(hits), query)

	return object_list(
		request,
		queryset=queryset,
		paginate_by=20,
		page=page,
        allow_empty=True,
		extra_context={
			"form": form,
			"queryset": queryset,
		},
		template_name="search_admin_search.html",
	)




"""
Description
-----------


ChangeLog
---------


Usage
-----


"""

__author__ =  "Spike^ekipS <spikeekips@gmail.com>"
__version__=  "0.1"
__nonsense__ = ""






